package com.goodlearning.gloriamobile.commons;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.URL;
import java.net.URLConnection;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.os.Parcelable;
import android.preference.PreferenceManager;
import android.provider.MediaStore.MediaColumns;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.Log;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.goodlearning.gloriamobile.R;
import com.goodlearning.gloriamobile.commons.AutoScaleDialog;
import com.goodlearning.gloriamobile.net.JsonRequestThread.INetSuccessCallback;
import com.goodlearning.gloriamobile.net.JsonWrapper;

public class Utils {

	public static final boolean MODE_ON_JSONLIST = true;
	public static final boolean MODE_ON_LOG_FILE = true;
	public static final boolean MODE_ON_PRINTLOG = true;
	public static final boolean MODE_ON_PRINTSTREAM = true;
	public static AutoScaleDialog autoScaleDialog;
	private static final String TAG = "log";
	ProgressDialog prgDlg = null;
	/**
	 * Stream을 복제
	 * 
	 * @author kyh
	 */
	/*
	 * static public class CopyInputStream { private InputStream _is; private
	 * ByteArrayOutputStream _copy = new ByteArrayOutputStream(); public
	 * CopyInputStream(InputStream is) { _is = is; try { copy(); } catch
	 * (IOException ex) { // do nothing } } private int copy() throws
	 * IOException { int read = 0; int chunk = 0; byte[] data = new byte[256];
	 * while (-1 != (chunk = _is.read(data))) { read += data.length;
	 * _copy.write(data, 0, chunk); } return read; } public InputStream
	 * getCopy() { return new ByteArrayInputStream(_copy.toByteArray()); } }
	 */

	/**
	 * out of memory가 나는 것을 막기 위해 이미지 옵션 조정해서 뷰에 적용
	 */
	public static void setContentBackgroundDrawable(Context context,
			int imgResId, View view) {
		/*
		 * for (int i = 0; i < applicationwayImgResIds.length; i++) {
		 * ((BitmapDrawable
		 * )getResources().getDrawable(applicationwayImgResIds[i]
		 * )).getBitmap().recycle(); }
		 */
		Options opt = new Options();
		opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
		opt.inSampleSize = 1;
		opt.inPurgeable = true;
		Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
				imgResId, opt);
		Drawable drawable = new BitmapDrawable(bitmap);
		view.setBackgroundDrawable(drawable);
	}
	/**
	 * 비대칭 V 가져오란다 씨발
	 * @param var
	 */
	public static char getASC(int var){
		Character varResult=(char)var;
		Utils.log("Var_Result:"+"["+varResult+"]");
		return varResult;
	}
	
	/**
	  * 해당 년, 월의 총 일수를 구한다.
	  */
	public static int getMonthTotalDays(int year, int mon)
	{
		Calendar cal = Calendar.getInstance();
		cal.set(Calendar.YEAR, year);
		cal.set(Calendar.MONTH, mon-1);
		cal.set(Calendar.DATE, 1);

		cal.add(Calendar.MONTH, 1);
		cal.add(Calendar.DATE, -1);
		return cal.get(Calendar.DATE);
	}
	/**
	 * 금액 천단위로 나누어서 , 찍음
	 * @param d
	 * @return
	 */
	public static String numberFormatComma(int d){
		DecimalFormat decimalFormat=new DecimalFormat("#,###");
		String numberFormat=decimalFormat.format(d);
		return numberFormat;
	}
	/**
	 * 뺄셈
	 * @param a
	 * @param b
	 * @return
	 */
	public static String getMinor(int a,int b){
		int c = a - b;
		String minorResult=String.valueOf(c);
		return minorResult;
	}
	/**
	 * 덧셈
	 * @param a
	 * @param b
	 * @return
	 */
	public static String getAdd(int a,int b){
		int c = a + b;
		String addResult=String.valueOf(c);
		return addResult;
	}
	/**
	 * 
	 * @param a
	 * @param b
	 * @return string
	 */
	public static String getDivide(int a,int b){
		int c= a / b;
		String divideResult=String.valueOf(c);
		return divideResult;
	}
	/**
	 * 나눈 나머지
	 * @param a
	 * @param b
	 * @return string
	 */
	public static String getLeftOverByDivide(int a,int b){
		int c= a % b;
		String leftOver=String.valueOf(c);
		return leftOver;
	}
	/**
	 * 문자열 데이터 Check
	 * @param data
	 * @return
	 */
	public static boolean isEmptyCheck(String data){
		if(!data.equals("0")){
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 
	 * @param compare 비교하려는 대상의  Data
	 * @param data 비교 대상 결과값
	 * @return true/false 
	 */
	public static boolean isDataCheck(String compare,String data){
		
		if(compare.equals(data)){
			return true;
		}
		
		return false;
	}
	/**
	 * Touch Event 막기 원하는 View 
	 * @param view
	 * @param resourceId
	 */
	public static void preventTouchEvent(View view,int resourceId){
		View viewPreventByTouch=view.findViewById(resourceId);
		viewPreventByTouch.setOnTouchListener(new View.OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				return true;
			}
		});
	}
	
	/**
	 * acceptTouch true 면 터치 이벤트를 막는다.
	 * false 이면 터치를 해제한다.
	 * @param view
	 * @param acceptTouch
	 */
	public static void preventTouchEventType(View view,final boolean acceptTouch){
		view.setOnTouchListener(new View.OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				Utils.log("AcceptTouchResult:"+"["+acceptTouch+"]");
				return acceptTouch ? true : false;
			}
		});
	}

/**
	 * 카카오톡 이미지 전달하기 API 정의
	 * @param kaPath
	 */
	public void sendImgToKaTalk(String kaPath,Context context){
		
		PackageManager packageManager=context.getPackageManager();
		
		try {
			
			if(packageManager.getApplicationInfo("com.kakao.talk", PackageManager.GET_META_DATA) != null){
				/**
				 * URI File
				 */
				Uri dataUri = Uri.parse("file://"+kaPath);
				Intent kakao = new Intent(Intent.ACTION_SEND);
				kakao.setType("image/*");
				kakao.putExtra(Intent.EXTRA_STREAM, dataUri);

				// KakaoTalk Package
				kakao.setPackage("com.kakao.talk");
				context.startActivity(kakao);
			}else{
				Toast.makeText(context, "폰에 카카오톡이 설치 되어있지 않습니다.", Toast.LENGTH_SHORT).show();
				return;
			}
			
		} catch (NameNotFoundException e) {
			e.printStackTrace();
			Utils.log(e.getMessage());
			if(e.getMessage()!=null){
				Toast.makeText(context, "폰에 카카오톡이 설치 되어있지 않습니다.", Toast.LENGTH_SHORT).show();
			}
		}
		
	}
	/**
	 * 
	 * @param context
	 * @param sendBytext
	 * @param subjectByText
	 * @param dialog
	 * @param showProgressDialog
	 */
	public static void kakaoProgress(final Context context,final String sendBytext,final String subjectByText,final boolean showProgressDialog){
		ProgressDialog prgDlg = null;
		
		if(showProgressDialog==true){
			prgDlg = ProgressDialog.show(context, "", "",true,true);
			prgDlg.getWindow().setContentView(R.layout.progressbar);
		}
		
			sendTextToKaKaoTalk(sendBytext, subjectByText, context, prgDlg, showProgressDialog);
		}
	
	/**
	 * KaKao Talk 문자 보내기 Intent 처리 및 예외 처리 포함
	 * @param sendBytext
	 * @param subjectByText
	 * @param context
	 */
	public static void sendTextToKaKaoTalk(String sendBytext,String subjectByText,Context context,ProgressDialog dialog,boolean showProgressDialog){
		
		PackageManager packageManager=context.getPackageManager();
		
		try{
			
			if(packageManager.getApplicationInfo("com.kakao.talk", PackageManager.GET_META_DATA) != null){
				
				Utils.log("==========send_kakao_intent=======");
				
				Toast.makeText(context, "메세지 전달을 위해 카카오톡으로 이동합니다.", Toast.LENGTH_SHORT).show();
				
				Intent kakao = new Intent(Intent.ACTION_SEND);
				kakao.setType("text/plain");
				kakao.setPackage("com.kakao.talk");
				kakao.putExtra(Intent.EXTRA_SUBJECT, subjectByText);
				kakao.putExtra(Intent.EXTRA_TEXT, sendBytext);
				
				Utils.log("==========start_kakao_activity=======");
				
				showProgressDialog = false;
				
				if(showProgressDialog==false){
					
					Utils.log("==================Dialog Dismiss==========");
					dialog.dismiss();
					context.sendBroadcast(kakao);
					context.startActivity(kakao);
				}
			}
			
		}catch (Exception e) {
			
			e.printStackTrace();
			
			Utils.log("Exception_Message_From_KaKao_Talk:"+"["+e.getMessage()+"]");
			
			if(isEmptyCheck(e.getMessage())){
				dialog.dismiss();
				Toast.makeText(context, "폰에 카카오톡이 설치 되어있지 않습니다.", Toast.LENGTH_SHORT).show();
			}
		}finally{
			if(dialog != null){
				try {
					dialog.dismiss();
				} catch (Exception e) {
					
				}
			}
		}
	}
	/**
	 * http://ememomo.tistory.com/entry/Intent-%ED%99%9C%EC%9A%A9-TYPE-%EC%A0%95%EB%A6%AC
	 * 디바이스 내부 일반 SMS 문자 수신 기능
	 * @param context
	 * @param smsText
	 */
	public static void sendSMSData(Context context,String smsText){
		Intent intent = new Intent(Intent.ACTION_VIEW);
		intent.putExtra("sms_body", smsText);
		intent.setType("vnd.android-dir/mms-sms");
		context.startActivity(intent);
	}
	/**
	 * http://ememomo.tistory.com/entry/Intent-%ED%99%9C%EC%9A%A9-TYPE-%EC%A0%95%EB%A6%AC
	 * Email 수신 기능
	 * @param context
	 * @param sendByCC
	 * @param sendBySubject
	 * @param sendByMessage
	 */
	public static void sendEmailData(Context context,String sendByCC,String sendBySubject,String sendByMessage){
		Intent it = new Intent(Intent.ACTION_SEND);    
		
//		String[] tos = {"me@abc.com"};     
//		String[] ccs = {"you@abc.com"};     
//		it.putExtra(Intent.EXTRA_EMAIL, tos);     
//		it.putExtra(Intent.EXTRA_CC, ccs);  
		
		it.putExtra(Intent.EXTRA_TEXT, sendByMessage);     
		it.putExtra(Intent.EXTRA_SUBJECT, sendBySubject);     
		it.setType("message/rfc822");     
		context.startActivity(Intent.createChooser(it, "이메일 방식 선택"));
		Toast.makeText(context, "메일을 선택하여 주세요", Toast.LENGTH_SHORT).show();
	}
	
	/**
	 * autoScaleDialog 이다 용도에 맞게 변경 가능하도록 GC 까지 마감 처리 한다. 오류 대비
	 * 
	 * @return
	 */
	public static com.goodlearning.gloriamobile.commons.AutoScaleDialog autoScaleDialog(Context context, int layoutResID) {
		// if (context != null || layoutResID!=0) {

		autoScaleDialog = new AutoScaleDialog(context);
		autoScaleDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		autoScaleDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
		autoScaleDialog.setContentView(layoutResID);
		autoScaleDialog.show();

		// }else {
		// Utils.log("[Dialog reference null]");
		// // autoScaleDialog.dismiss();
		// // autoScaleDialog=null;
		// }
		return autoScaleDialog;
	}
	/**
	 * 안드로이드 기본 activity 전환
	 * 
	 * @param context
	 * @param class1
	 */
	public static void changeActivity(Context context, Class<?> class1) {
		Intent intent = new Intent(context, class1);
		context.startActivity(intent);
	}
	/**
	 * Intent Flag (사용자 선택)
	 * 전달될때 사용되는 Key, 전달될 객체 parcelable
	 * @param context
	 * @param class2
	 * @param Flag
	 * @param key
	 * @param parcelable
	 */
	public static void changeActivityNSendData(Context context,Class<?>class2,int Flag,String key,Parcelable parcelable){
		Intent intent=new Intent(context, class2).setFlags(Flag);
		intent.putExtra(key, parcelable);
		context.startActivity(intent);
	}
	/**
	 * Stream 복제
	 * 
	 * @param is
	 * @return
	 */
	public static InputStream copyInputStream(InputStream is) {
		InputStream _is;
		ByteArrayOutputStream _copy = new ByteArrayOutputStream();
		_is = is;
		try {
			int chunk = 0;
			byte[] data = new byte[256];
			while (-1 != (chunk = _is.read(data))) {
				_copy.write(data, 0, chunk);
			}
		} catch (IOException ex) {
			ePrintStackTrace(ex);
		}

		return new ByteArrayInputStream(_copy.toByteArray());
	}

	public interface ICommonCallback {
		public void execute();

	}

	/**
	 * Serializable된 객체의 Clone객체를 반환한다.
	 * 
	 * @param obj
	 * @return
	 * @throws Exception
	 */
	public static Object cloneViaSerialization(Serializable obj)
			throws Exception {
		ByteArrayOutputStream bytes = new ByteArrayOutputStream() {
			public synchronized byte[] toByteArray() {
				return buf;
			}
		};
		ObjectOutputStream out = new ObjectOutputStream(bytes);
		out.writeObject(obj);
		out.close();
		ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
				bytes.toByteArray()));
		Object objCopy = in.readObject();
		return objCopy;
	}

	/**
	 * File Seperator (File.separator) JAVA 내부에서 파일 경로지정 구분자이다. 리눅스든 어떤 운영시스템에서는
	 * 호환이 가능해야 함으로 IO 의 파일구분자를 가져다 쓴다.
	 * 
	 * @param context
	 * @return
	 */
	public static String getDbPath(Context context) {
		return Constants.DATA_PATH + File.separator + context.getPackageName()
				+ File.separator + Constants.DATABASE_FOLDER_NAME;
	}

	/**
	 * Assets의 db 파일을 이용해 DataBase를 생성한다.
	 * 
	 * @throws IOException
	 */
	public static void copyDataBase(Context ctx) throws IOException {
		// showLog("getDbPath(ctx)+File.separator+Constants.DATABASE_FILE_NAME : "+getDbPath(ctx)+File.separator+Constants.DATABASE_FILE_NAME);
		String dbFile = getDbPath(ctx) + File.separator
				+ Constants.DATABASE_FILE_NAME;
		if (!new File(getDbPath(ctx)).exists()) {
			new File(getDbPath(ctx)).mkdirs();
			// Log.d("",
			// "~~~~ new File(CommonFields.DATABASE_PACKAGE).mkdirs()");
		}
		// System.out.println(new File(dbFile).exists());
		if (new File(dbFile).exists())
			return;

		InputStream myInput = ctx.getAssets()
				.open(Constants.DATABASE_FILE_NAME);
		OutputStream myOutput = new FileOutputStream(dbFile);

		byte[] buffer = new byte[1024];
		int length;
		while ((length = myInput.read(buffer)) > 0) {
			myOutput.write(buffer, 0, length);
		}

		myOutput.flush();
		myOutput.close();
		myInput.close();
	}

	/** 영문~숫자만 받기 필터 **/
	public static final InputFilter FILTER_ENG_NUM = new InputFilter() {
		@Override
		public CharSequence filter(CharSequence source, int start, int end,
				Spanned dest, int dstart, int dend) {
			Pattern ps = Pattern.compile("^[a-zA-Z0-9]+$");
			if (!ps.matcher(source).matches()) {
				return "";
			}
			return null;
		}
	};

	/** 한글만 받기필터 **/
	public static final InputFilter FILTER_KOR = new InputFilter() {
		@Override
		public CharSequence filter(CharSequence source, int start, int end,
				Spanned dest, int dstart, int dend) {
			Pattern ps = Pattern.compile("^[ㄱ-ㅎ가-흐]+$");
			if (!ps.matcher(source).matches()) {
				return "";
			}
			return null;
		}
	};

	/** 숫자만 받기필터 **/
	public static final InputFilter FILTER_NUM = new InputFilter() {
		@Override
		public CharSequence filter(CharSequence source, int start, int end,
				Spanned dest, int dstart, int dend) {
			Pattern ps = Pattern.compile("^[0-9]+$");
			if (!ps.matcher(source).matches()) {
				return "";
			}
			return null;
		}
	};

	/** 영문,한글,숫자만 받기필터 **/
	public static final InputFilter FILTER_ENG_KOR_NUM = new InputFilter() {
		@Override
		public CharSequence filter(CharSequence source, int start, int end,
				Spanned dest, int dstart, int dend) {
			Pattern ps = Pattern.compile("^[ㄱ-ㅎ가-흐a-zA-Z0-9]+$");
			if (!ps.matcher(source).matches()) {
				return "";
			}
			return null;
		}
	};

	/**
	 * 안드로이드 Call
	 * 
	 * @param context
	 * @param action
	 * @param uri
	 */
	public static void intentCallCustom(Context context, String action, Uri uri) {
		Intent intent = new Intent(action, uri);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		context.startActivity(intent);
	}

	/*
	 * private static Handler commonHandler = new Handler() {
	 * 
	 * @Override public void handleMessage(Message msg) {
	 * super.handleMessage(msg); ((ICommonCallback) msg.obj).execute(); } };
	 */

	/**
	 * EditText에 InputFilter를 추가한다.
	 */
	public static void addFilter(EditText et, InputFilter filter) {
		InputFilter[] beforeFilters = et.getFilters();
		InputFilter[] afterFilters = new InputFilter[beforeFilters.length + 1];
		for (int i = 0; i < beforeFilters.length; i++) {
			afterFilters[i] = beforeFilters[i];
		}
		afterFilters[afterFilters.length - 1] = filter;
		et.setFilters(afterFilters);
	}

	public static boolean checkJumin(String jumin) {
		int arr[] = { 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5 };
		int sum = 0;
		byte[] by = jumin.getBytes();

		if (by.length != 13) {
			return false;

		} else {
			for (int i = 0; i < by.length - 1; i++) {
				sum += (by[i] - 48) * arr[i];
			}
		}

		int num = 0;
		int num2 = 0;
		num = sum % 11;

		if (num != 0 || num != 1) {
			num2 = 11 - num;
			if (num2 == by[12] - 48) {
				return true;

			} else {
				num2 = num + 1;
				if (num2 == by[12] - 48)
					return true;
				else
					return false;
			}

		} else {
			return false;
		}
	}

	/**
	 * 첫째 인자와 뒷인자들중 하나라도 일치하면 true
	 * 
	 * @param userId
	 * @param string
	 * @param string2
	 * @param string3
	 * @param string4
	 * @param string5
	 * @return
	 */
	public static boolean confirmAnd(String userId, String... str) {
		boolean confirm = true;
		for (int i = 0; i < str.length; i++) {
			if (!userId.equals(str[i])) {
				confirm = false;
				break;
			}
		}
		return confirm;
	}

	/**
	 * 첫째 인자와 뒷인자들중 하나라도 일치하면 true
	 * 
	 * @param userId
	 * @param string
	 * @param string2
	 * @param string3
	 * @param string4
	 * @param string5
	 * @return
	 */
	public static boolean confirmOr(String userId, String... str) {
		boolean confirm = false;
		for (int i = 0; i < str.length; i++) {
			if (userId.equals(str[i])) {
				confirm = true;
				break;
			}
		}
		return confirm;
	}

	public static String convertObjToString(Object strObj) {
		return strObj == null ? "" : String.valueOf(strObj);
	}

	public static int convertObjToInt(Object strObj) {
		String str = convertObjToString(strObj);
		return "".equals(str) ? 0 : Integer.parseInt(str);
	}

	/**
	 * 파일삭제
	 */
	public static List<File> deleteFile(List<File> files) {
		List<File> failedList = new ArrayList<File>();
		FileInputStream fis = null;
		FileOutputStream fos = null;
		for (int i = 0; i < files.size(); i++) {
			try {
				fis = new FileInputStream(files.get(i));
				fos = new FileOutputStream(fis.getFD());
				fos.write(1);
				fos.flush();
				System.gc();
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				ePrintStackTrace(e);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				ePrintStackTrace(e);

			} finally {
				if (fis != null) {
					try {
						fis.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						ePrintStackTrace(e);
					}
				}
				if (fos != null) {
					try {
						fos.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						ePrintStackTrace(e);
					}
				}
			}

			if (!files.get(i).delete()) {
				failedList.add(files.get(i));
				Utils.log("fail deleted - " + files.get(i));
			} else {
				Utils.log("deleted - " + files.get(i));
			}

		}
		return failedList;
	}

	/**
	 * 입력된 디렉토리의 하위 모든 파일을 얻는다.
	 * 
	 * @param root
	 * @param files
	 * @return
	 */
	public static List<File> getAllChildFiles(File root, List<File> files) {
		if (root.listFiles() == null) {
			return files;
		}
		for (int i = 0; i < root.listFiles().length; i++) {
			File file = root.listFiles()[i];
			if (file.isDirectory()) {
				getAllChildFiles(file, files);
			}
			files.add(file);
		}
		return files;
	}

	/**
	 * SharedPreferences에서 boolean조회
	 */
	public static boolean getBooleanByPreference(Context context, String key,
			boolean defValue) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		return prefs.getBoolean(key, defValue);
	}

	/**
	 * SharedPreferences에서 float조회
	 */
	public static float getFloatByPreference(Context context, String key,
			float defValue) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		return prefs.getFloat(key, defValue);

	}

	public static String getImageExtName(String string) {
		if ("jpeg".equals(string)) {
			return "jpg";
		}
		return null;
	}

	/**
	 * SharedPreferences에서 int조회
	 */
	public static int getIntByPreference(Context context, String key,
			int defValue) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		return prefs.getInt(key, defValue);

	}

	/**
	 * SharedPreferences에서 long조회
	 */
	public static long getLongByPreference(Context context, String key,
			long defValue) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		return prefs.getLong(key, defValue);

	}

	/**
	 * URI로 부터 실제 파일 경로를 가져온다.
	 * 
	 * @param uriPath
	 *            URI : URI 경로
	 * @return String : 실제 파일 경로
	 */
	public static String getRealImagePath(Context ctx, Uri uriPath)
			throws Exception {
		String[] proj = { MediaColumns.DATA };
		Cursor cursor = ((Activity) ctx).managedQuery(uriPath, proj, null,
				null, null);
		int index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);
		cursor.moveToFirst();
		String path = cursor.getString(index);
		// path = path.substring(Constants.PAGE_MAX_ROW);
		return path;
	}

	/**
	 * sdcard경로 조회
	 * 
	 * @return
	 */
	public static String getSdPath() {
		String exist = Environment.getExternalStorageState();
		String mSdPath;
		if (exist.equals(Environment.MEDIA_MOUNTED)) {
			mSdPath = Environment.getExternalStorageDirectory()
					.getAbsolutePath();

		} else {
			mSdPath = Environment.MEDIA_UNMOUNTED;
		}
		return mSdPath;
	}

	/**
	 * SharedPreferences에서 String조회
	 */
	public static String getStringByPreference(Context context, String key,
			String defValue) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		return prefs.getString(key, defValue);
	}
	/**
	 * 입력된 일자를 9999년
	 * @return
	 */
	public static String changeYearFormat(String yyyymmdd){
	
		String rtnYear=null;
		String yyyy=yyyymmdd.substring(0, 4);
		rtnYear=yyyy;
		return rtnYear;
	}
	/**
	 * 99월 형태로 가져온다.
	 * @param yyyymmdd
	 * @return
	 */
	public static String changeMonthFormat(String yyyymmdd){
		
		String rtnMonth=null;
		String mm=yyyymmdd.substring(4, 6);
		rtnMonth=mm;
		return rtnMonth;
	}
	/**
	 * 일 형태 리턴
	 * @param yyyymmdd
	 * @return
	 */
	public static String changeDayFormat(String yyyymmdd){
		String rtnDay=null;
		String dd= yyyymmdd.substring(6, 8);
		rtnDay=dd;
		return rtnDay;
	}
	/**
	 * 요일 형태 리턴
	 * @param yyyymmdd
	 * @return
	 */
	public static String changeEFormat(String yyyymmddE){
		String rtnWeek=null;
		String dd= yyyymmddE.substring(8, 9);
		rtnWeek=dd;
		return rtnWeek;
	}
	/**
	 * select 가 0 이면
	 * @return
	 */
	public static String getCurrentYearAndMonth(int addMonthVal,int select){
		
		SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMddE",Locale.KOREA);
		Calendar today = new GregorianCalendar();
		today.add(Calendar.MONTH, addMonthVal);

		String dTime = dateFormat.format ( today.getTime() );
		
		String data="";
		
		if(select==0){
			data=changeYearFormat(dTime);
		}else if(select==1){
			data=changeMonthFormat(dTime);
		}else if(select==2){
			data=changeDayFormat(dTime);
		}else if(select==3){
			data=changeEFormat(dTime);
		}else{
			
			data="Result is none";
		}
		return data;
	}
	
	/**
	 * 해당웡의 일
	 * @param addMonthVal
	 * @param select
	 * @return
	 */
	
	public static String getCurrentDayAdd(int addMonthVal,int select){
		SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMddE",Locale.KOREA);
		Calendar today = new GregorianCalendar();
		today.add(Calendar.DAY_OF_MONTH, addMonthVal);
		
		String dTime = dateFormat.format ( today.getTime() );
		String data="";
		
		Utils.log("D_TIME:"+"["+dTime+"]");
		
		if(select==0){
			data=changeYearFormat(dTime);
		}else if(select==1){
			data=changeMonthFormat(dTime);
		}else if(select==2){
			data=changeDayFormat(dTime);
		}else if(select==3){
			data=changeEFormat(dTime);
		}else{
			
			data="Result is none";
			
		}
		return data;
	}
//	/**
//	 * http://k.daum.net/qna/openknowledge/view.html?qid=40EIz
//	 * 날짜에 대한 요일 가져오기 
//	 * @return
//	 */
//	public static String getDayOfWeek(){
//		
//	}
	
	/**
	 * 
	 * @param addYearVal
	 * @param select
	 * @return
	 */
	public static String getYearAddRemove(int addYearVal,int select){
		SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMdd",Locale.KOREA);
		Calendar today = new GregorianCalendar();
		today.add(Calendar.YEAR, addYearVal);

		String dTime = dateFormat.format ( today.getTime() );
		
		String data="";
		
		if(select==0){
			data=changeYearFormat(dTime);
		}else if(select==1){
			data=changeMonthFormat(dTime);
		}else if(select==2){
			data=changeDayFormat(dTime);
		}else{
			
			data="Result is none";
		}
		return data;
	}
	
	/**
	 * 오늘 현재 날짜
	 * @return
	 */
	public static String getCurrentToday(int dateInt){
		
		String todayDetail=Utils.getCurrentYearAndMonth(dateInt, 0)+"-"
				+Utils.getCurrentYearAndMonth(dateInt, 1)+"-"
				+Utils.getCurrentYearAndMonth(dateInt, 2);
		
		return todayDetail;
	}
	
	/*
	 * public static void handle(ICommonCallback icc) { Message msg = new
	 * Message(); msg.obj = icc; commonHandler.sendMessage(msg); }
	 */

	// /**
	// * 공용 로그인
	// *
	// * @param context
	// */
	// public static void requestLogin(final Context context, final ICallback
	// succCallback, final ICallback failCallback) {
	// final String userId = Utils.getStringByPreference(context,
	// Constants.PRE_STRING_USER_ID, null);
	// String userPw = Utils.getStringByPreference(context,
	// Constants.PRE_STRING_USER_PW, null);
	// if ((userId == null || "".equals(userId)) || (userPw == null ||
	// "".equals(userPw))) {
	// failCallback.sendCallback(null);
	// return;
	// }
	//
	// XmlServiceRequester.requestLogin(context, userId, userPw, new
	// IXmlNetCallback() {
	// @Override
	// public void sendCallback(XmlWrapper xmlWrapper) {
	// if ("OK".equals(xmlWrapper.selectSingleNodeText("/respData/result"))) {
	// // 로그인 성공
	// Constants.userId = userId;
	// succCallback.sendCallback(null);
	//
	// } else {
	// Constants.userId = null;
	// failCallback.sendCallback(null);
	// // 로그인실패
	//
	// }
	//
	// }
	// });
	// }

	public static String saveUrlImageFile(Context context, String urlSpec) {
		BufferedInputStream bis = null;
		FileOutputStream fos = null;
		String writeFullPath = null;

		try {
			URL url = new URL(urlSpec);
			String urlPath = url.getPath();
			int idx = url.getPath().lastIndexOf("/");
			String urlDirPath = urlPath.substring(0, idx + 1);
			String urlFileName = urlPath.substring(idx + 1);

			String writeExternalDir = Environment.getExternalStorageDirectory()
					+ "/" + context.getPackageName() + urlDirPath;
			File dir = new File(writeExternalDir);
			if (!dir.exists()) {
				dir.mkdirs();
			}

			writeFullPath = writeExternalDir + urlFileName;

			File existFile = new File(writeFullPath);
			if (existFile.exists()) {
				return writeFullPath;
			}

			URLConnection conn = url.openConnection();
			File wFile = new File(writeFullPath);
			bis = new BufferedInputStream(conn.getInputStream());
			fos = new FileOutputStream(wFile);
			byte[] buf = new byte[2048];
			int read = 0;
			while ((read = bis.read(buf)) != -1) {
				fos.write(buf, 0, read);
				fos.flush();
			}

		} catch (Exception e) {
			ePrintStackTrace(e);

		} finally {
			try {
				if (bis != null) {
					bis.close();
				}
				if (fos != null) {
					fos.close();
				}
			} catch (Exception e) {
				ePrintStackTrace(e);
			}

		}

		return writeFullPath;

	}

	/**
	 * SharedPreferences에 boolean저장
	 */
	public static void setPreference(Context context, String key, boolean value) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		SharedPreferences.Editor pre = prefs.edit();
		pre.putBoolean(key, value);
		pre.commit();
	}

	/**
	 * SharedPreferences에 float저장
	 */
	public static void setPreference(Context context, String key, float value) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		SharedPreferences.Editor pre = prefs.edit();
		pre.putFloat(key, value);
		pre.commit();
	}

	/**
	 * SharedPreferences에 int저장
	 */
	public static void setPreference(Context context, String key, int value) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		SharedPreferences.Editor pre = prefs.edit();
		pre.putInt(key, value);
		pre.commit();
	}

	/**
	 * SharedPreferences에 long저장
	 */
	public static void setPreference(Context context, String key, long value) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		SharedPreferences.Editor pre = prefs.edit();
		pre.putLong(key, value);
		pre.commit();
	}

	/**
	 * SharedPreferences에 String저장
	 */
	public static void setPreference(Context context, String key, String value) {
		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(context);
		SharedPreferences.Editor pre = prefs.edit();
		pre.putString(key, value);
		pre.commit();
	}

	public static void setUriImageTo(ImageView iv, Object object) {
		if (object != null) {
			String str = object.toString();
			if (!"".equals(str)) {
				Uri uri = Uri.parse(str);
				if (uri != null) {
					iv.setImageURI(uri);
					iv.setTag(uri);
				}
			}
		}

	}

	/**
	 * 예/아니오 선택 다이얼로그 호출
	 */
	public static void showConfirmDialog(Context context, String title,
			String msg, DialogInterface.OnClickListener yesListner,
			DialogInterface.OnClickListener noListner) {
		new AlertDialog.Builder(context).setTitle(title).setMessage(msg)
				.setPositiveButton("예", yesListner)
				.setNegativeButton("아니오", noListner).create().show();
	}

	/**
	 * 네트워크 결과 알림 다이얼로그 호출
	 */
	public static void showNetNoticeDialog(Context context, String title,
			String msg, final INetSuccessCallback callback,
			final JsonWrapper jsonWrapper) {
		new AlertDialog.Builder(context).setCancelable(false).setTitle(title)
				.setMessage(msg)
				.setPositiveButton("확인", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int id) {
						if (callback != null) {
							callback.sendCallback(jsonWrapper);
						}

					}
				}).create().show();
	}
	
	/**
	 * 확인 팝업으로 변경
	 */
	public static void showConfirmNoticeDialog(Context context, String title,String msg) {
		new AlertDialog.Builder(context).setCancelable(false).setTitle(title)
				.setMessage(msg)
				.setPositiveButton("확인", new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int id) {
						

					}
				}).create().show();
	}

	// /**
	// * 알림 다이얼로그 호출
	// */
	// public static void showNoticeDialog(Context context, String title, String
	// msg, final ICallback callback, final Map<String, String> rtnMap) {
	// AlertDialog dlgBuilder = new
	// AlertDialog.Builder(context).setTitle(title).setMessage(msg)
	// .setPositiveButton("확인", new DialogInterface.OnClickListener() {
	// @Override
	// public void onClick(DialogInterface dialog, int id) {
	// if (callback != null) {
	// callback.sendCallback(rtnMap);
	// }
	//
	// }
	// }).create();
	// dlgBuilder.show();
	// dlgBuilder.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
	// WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
	//
	// }

	/**
	 * e.printStackTrace(); 실행
	 * 
	 * @param e
	 */
	public static void ePrintStackTrace(Exception e) {
		if (MODE_ON_PRINTSTREAM) {
			e.printStackTrace();
		}
		if (MODE_ON_LOG_FILE) {
			writeLogFile("! Exception : message -" + e.getMessage());
			for (int i = 0; i < e.getStackTrace().length; i++) {
				writeLogFile("! Exception : at "
						+ e.getStackTrace()[i].getFileName() + " [LINE : "
						+ e.getStackTrace()[i].getLineNumber() + "]");
			}

		}
	}

	public static void log(Object obj) {
		if (MODE_ON_PRINTLOG) {
			StackTraceElement ste = new Throwable().getStackTrace()[1];
			Log.d(TAG,
					String.format("%50s",
							ste.getFileName() + "." + ste.getMethodName() + "("
									+ ste.getLineNumber() + ")")
							+ " - ["
							+ (obj == null ? "null" : obj.toString())
							+ "]");
			// System.out.println("logFos : "+logFos);
		}

		if (MODE_ON_LOG_FILE) {
			StackTraceElement ste = new Throwable().getStackTrace()[1];
			writeLogFile(String.format(
					"%50s",
					ste.getFileName() + "." + ste.getMethodName() + "("
							+ ste.getLineNumber() + ")")
					+ " - [" + (obj == null ? "null" : obj.toString()) + "]");
		}

	}

	private static FileOutputStream logFos = null;
	private static String logFileName = Constants.SDF_YMD.format(Calendar
			.getInstance().getTime());

	/**
	 * 로그파일을 작성한다.
	 * 
	 * @param string
	 */
	private synchronized static void writeLogFile(String string) {
		try {
			String yyyyMMddHHmmss = Constants.SDF_Y_M_D_H_M_S.format(Calendar
					.getInstance().getTime());
			String msg = yyyyMMddHHmmss + " : " + string + "\n";
			if (logFos == null) {
				if (!Constants.LOG_FILE_PATH.exists()) {
					if (Constants.LOG_FILE_PATH.mkdirs()) {
						logFos = new FileOutputStream(new File(
								Constants.LOG_FILE_PATH, logFileName + ".log"),
								true);
					}
				} else {
					logFos = new FileOutputStream(new File(
							Constants.LOG_FILE_PATH, logFileName + ".log"),
							true);
				}
			} else {
				String tempFileName = Constants.SDF_YMD.format(Calendar
						.getInstance().getTime());
				if (!tempFileName.equals(logFileName)) {
					logFos.close();
					logFileName = tempFileName;
					if (!Constants.LOG_FILE_PATH.exists()) {
						if (Constants.LOG_FILE_PATH.mkdirs()) {
							logFos = new FileOutputStream(new File(
									Constants.LOG_FILE_PATH, logFileName
											+ ".log"), true);
						}
					} else {
						logFos = new FileOutputStream(new File(
								Constants.LOG_FILE_PATH, logFileName + ".log"),
								true);
					}
				}
			}
			if (logFos != null) {
				logFos.write(msg.getBytes(), 0, msg.getBytes().length);
				logFos.flush();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * System.out.println을 사용
	 * 
	 * @param obj
	 */
	/*
	 * public static void showOutPrintLog(String obj) { if (MODE_ON_PRINTSTREAM)
	 * { StackTraceElement ste = new Throwable().getStackTrace()[1];
	 * System.out.println( String.format("%40s", ste.getFileName() + "." +
	 * ste.getMethodName() + "(" + ste.getLineNumber() + ")") + " - [" + (obj ==
	 * null ? "null" : obj.toString()) + "]"); }
	 * 
	 * }
	 */

	/**
	 * 로깅시점 이전의 모든 StrackTrace를 출력
	 * 
	 * @param obj
	 */
	public static void showStackTrace(String obj) {
		if (MODE_ON_PRINTLOG) {
			Log.d(TAG,
					"__________________________________________________________________ Stack Trace ___________________________________________________________________________");
			StackTraceElement[] steArr = new Throwable().getStackTrace();
			for (int i = 1; i < steArr.length; i++) {
				StackTraceElement ste = steArr[i];
				Log.d(TAG,
						String.format("%40s",
								ste.getFileName() + "." + ste.getMethodName()
										+ "(" + ste.getLineNumber() + ")"));
			}
			Log.d(TAG, "Message : " + obj == null ? "null" : obj.toString());
			Log.d(TAG,
					"___________________________________________________________________________________________________________________________________________________________");

		}
	}

	/**
	 * 두인자가 null일지라도 예외가 발생하지 않고 equals비교를 한다.
	 * 
	 * @param obj1
	 * @param obj2
	 * @return 둘중 하나라도 null일경우 false, 그외의경우 Object.equals와 동일
	 */
	public static boolean equals(String obj1, String obj2) {
		if (obj1 == null || obj2 == null) {
			return false;
		}
		return obj1.equals(obj2);
	}

	/**
	 * Static Class 를 정의 함
	 * 
	 * @author rapty54
	 * 
	 */
	public static class Scale {
		public float scaleX;
		public float scaleY;
	}

	/**
	 * 현재 Scale 즉 화면의 비를 구하는 함수
	 * 
	 * @param context
	 * @param width
	 * @param height
	 * @return
	 */
	public static Scale getScale(Context context, int width, int height) {
		boolean isLandscape = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
		Utils.log("Landscape:" + "[" + isLandscape + "]");
		float frameBufferWidth = isLandscape ? height : width;
		float frameBufferHeight = isLandscape ? width : height;
		Utils.log("frameBufferWidth:" + "[" + frameBufferWidth + "]"
				+ "frameBufferHeight:" + "[" + frameBufferHeight + "]");
		Scale scale = new Scale();
		Utils.log("Display Width:"
				+ "["
				+ (float) ((WindowManager) context
						.getSystemService(Context.WINDOW_SERVICE))
						.getDefaultDisplay().getWidth()
				+ "]"
				+ "Display Height:"
				+ "["
				+ (float) ((WindowManager) context
						.getSystemService(Context.WINDOW_SERVICE))
						.getDefaultDisplay().getHeight() + "]");
		scale.scaleX = (float) ((WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
				.getWidth()
				/ frameBufferWidth;
		scale.scaleY = (float) ((WindowManager) context
				.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay()
				.getHeight()
				/ frameBufferHeight;
		Utils.log("ScaleX:" + "[" + scale.scaleX + "]" + "/" + "ScaleY" + "["
				+ scale.scaleY + "]");
		return scale;
	}

	public static void applyScale(View view, Scale scale,
			boolean changeOnlyFont, View[] exceptViewArr) {

		Utils.log("exceptViewArr:" + "[" + exceptViewArr + "]" + "View:" + "["
				+ view + "]" + "Scale:" + "[" + scale != null ? "["
				+ scale.scaleX + "]" + "[" + scale.scaleY + "]" : "["
				+ scale.scaleX + "]" + "[" + scale.scaleY + "]" + "]"
				+ "ChangeOnlyFont:" + "[" + changeOnlyFont + "]");

		if (view == null) {
			return;
		}

		if (scale.scaleX == 1) {
			if (scale.scaleY == 1) {
				// log("scale.scaleY == 1 =  "+(scale.scaleY == 1));
				Utils.log("Scale_X:" + "[" + scale.scaleX + "]" + "Scale_y"
						+ "[" + scale.scaleY + "]");
				return;
			}
		}

		if (exceptViewArr != null) {
			for (int i = 0; i < exceptViewArr.length; i++) {
				if (view.equals(exceptViewArr[i])) {
					// log(view.getId() +"=="+ exceptViewIdArr[i] +
					// " - return!!");
					Utils.log("exceptViewArr:" + exceptViewArr[i]);
					return;
				}
			}
		}

		if (view instanceof TextView) {
			TextView tv = (TextView) view;
			// Utils.log("TextSize - "+tv.getTextSize() + " - > "+ (int)
			// (tv.getTextSize() * scale.scaleX));
			tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, tv.getTextSize()
					* scale.scaleX);
		}

		if (!changeOnlyFont) {
			// log("getPaddingLeft : " + view.getPaddingLeft() + " = >" +
			// (int)(view.getPaddingLeft() * scale.scaleX) );
			// log("getPaddingTop : " + view.getPaddingTop() + " = >" +
			// (int)(view.getPaddingTop() * scale.scaleY) );
			// log("getPaddingRight : " + view.getPaddingRight() + " = >" +
			// (int)(view.getPaddingRight() * scale.scaleX) );
			// log("getPaddingBottom : " + view.getPaddingBottom() + " = >" +
			// (int)(view.getPaddingBottom() * scale.scaleY) );
			Utils.log("Left:" + "["
					+ (int) (view.getPaddingLeft() * scale.scaleX) + "]"
					+ "Top:" + "["
					+ (int) (view.getPaddingTop() * scale.scaleY) + "]"
					+ "Right:" + "["
					+ (int) (view.getPaddingRight() * scale.scaleX) + "]"
					+ "Bottom:" + "["
					+ (int) (view.getPaddingBottom() * scale.scaleY) + "]");
			view.setPadding((int) (view.getPaddingLeft() * scale.scaleX),
					(int) (view.getPaddingTop() * scale.scaleY),
					(int) (view.getPaddingRight() * scale.scaleX),
					(int) (view.getPaddingBottom() * scale.scaleY));

			if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
				ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) view
						.getLayoutParams();

				if (0 <= lp.width) {
					// Utils.log("width - "+lp.width + " - > "+ (int) (lp.width
					// * scale.scaleX));
					lp.width = (int) (lp.width * scale.scaleX);
				}

				if (0 <= lp.height) {
					// Utils.log("height - "+lp.height + " - > "+ (int)
					// (lp.height * scale.scaleY));
					lp.height = (int) (lp.height * scale.scaleY);
				}

				// log("leftMargin : " + lp.leftMargin + " = >" +
				// (int)(lp.leftMargin * scale.scaleX) );
				// log("topMargin : " + lp.topMargin + " = >" +
				// (int)(lp.topMargin * scale.scaleY) );
				// log("rightMargin : " + lp.rightMargin + " = >" +
				// (int)(lp.rightMargin * scale.scaleX) );
				// log("bottomMargin : " + lp.bottomMargin + " = >" +
				// (int)(lp.bottomMargin * scale.scaleY) );

				lp.setMargins((int) (lp.leftMargin * scale.scaleX),
						(int) (lp.topMargin * scale.scaleY),
						(int) (lp.rightMargin * scale.scaleX),
						(int) (lp.bottomMargin * scale.scaleY));

			}

		}

		if (view instanceof AdapterView) {
			return;
		}

		if (view instanceof ViewGroup) {
			ViewGroup vg2 = (ViewGroup) view;
			for (int j = 0; j < vg2.getChildCount(); j++) {
				applyScale(vg2.getChildAt(j), scale, changeOnlyFont,
						exceptViewArr);
			}
		}

	}
}
